﻿using System;
using System.Collections.Generic;
using System.Linq;

using MvcCmsSocial.Data;
using MvcCms.Data;
using MvcCms.Data.Pagination;
using MvcCms.Service.Cache;
using MvcCms.Service.Code;
using MvcCms.Service;
using MvcCms.Service.Validation;
using MvcCms.Service.Logging;
using Microsoft.Practices.ServiceLocation;


namespace MvcCmsSocial.Service
{
    public class SocialService : ISocialService
    {
        #region Constructors

        private readonly ISocialRepository _repository;
        private readonly IMiscService _miscService;
        private readonly IValidationDictionary _validationDictionary;
     
        public SocialService(IValidationDictionary validationDictionary,
                              ISocialRepository repository, ICacheService cacheService, IMiscService miscService)
        {
            _validationDictionary = validationDictionary;
            _repository = repository;
            _miscService = miscService;
        }

        #endregion

        #region Validation Methods

        private bool ValidateSocialImage(SocialImage imageToValidate)
        {
            if (imageToValidate.User==null)
                _validationDictionary.AddError("User", "User is required");
            return _validationDictionary.IsValid;
        }
        #endregion

        public User GetUser(string userName)
        {
            return _repository.GetUser(userName);
        }

        #region Message Methods
        public DTOSocialMessage CreateSocialMessage(SocialMessage socialMessageToCreate, string messageType)
        {
            if (socialMessageToCreate.Body.Length == 0) { return null; }
            // Apply Business Rules
            var accountRepository = ServiceLocator.Current.GetInstance<IEntityAccountRepository>();
            
            
            socialMessageToCreate.FromUser = accountRepository.GetUser(socialMessageToCreate.FromUser.UserID);
            socialMessageToCreate.ToUser = accountRepository.GetUser(socialMessageToCreate.ToUser.UserID);
            socialMessageToCreate.AddedDate = DateTime.Now;

            socialMessageToCreate.Body = System.Web.HttpUtility.HtmlEncode(socialMessageToCreate.Body).ToComment();

            socialMessageToCreate.MessageType = new SocialMessageType {
                Name = messageType
            };

            // Database logic
            try
            {
                var newMessage = _repository.CreateSocialMessage(socialMessageToCreate);
                newMessage.ElapsedTime = newMessage.AddedDate.ToTimeSinceString();
                return newMessage;
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return null;
            }
        }
        public bool DeleteSocialMessage(SocialMessage socialMessageToDelete)
        {
            try
            {
                _repository.DeleteSocialMessage(socialMessageToDelete);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }
        public bool EditSocialMessage(SocialMessage socialMessageToEdit)
        {
            // Database logic
            try
            {
                _repository.EditSocialMessage(socialMessageToEdit);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }
        public DTOMessages ListSocialMessages(Guid userId, int pageNumber, int resultsPerPage)
        {
            var query = _repository.ListSocialMessages(userId).AsPagination(pageNumber, resultsPerPage);
            var dTOMessages = new DTOMessages();
            dTOMessages.GetPagination.PageNumber = pageNumber;
            dTOMessages.GetPagination.TotalItems = query.TotalItems;
            dTOMessages.GetPagination.PageSize = resultsPerPage;
            var messages = query.ToList();

            if (messages.Count() > 0)
            {
                foreach (var message in messages)
                {
                    var theirPic = "nophotoavailable.gif";
                    var theirPicObj = _repository.GetProfilePic(message.FromUser.UserID);
                    if (theirPicObj != null) { theirPic = theirPicObj.ImageName; }
                    var newMessage = new DTOMessage
                    {
                        Body = message.Body.ConvertUrlsToLinks(),
                        FromUserID = message.FromUser.UserID,
                        FromUserName = message.FromUser.UserName,
                        TheirPic = theirPic,
                        ElapsedTime = message.AddedDate.ToTimeSinceString(),
                        MessageID = message.MessageID,
                        Replies = _repository.ListSocialMessageReplies(message.MessageID),
                        Likes = message.Likes
                    };
                    dTOMessages.Add(newMessage);
                }
            }
            return dTOMessages;
        }
        #endregion

        #region Data Methods
        public bool CreateSocialData(SocialData socialDataToCreate)
        {

            // Database logic
            try
            {
                _repository.CreateSocialData(socialDataToCreate);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }
        public bool EditSocialData(SocialData socialDataToEdit)
        {
            // Database logic
            try
            {
                _repository.EditSocialData(socialDataToEdit);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }
        public SocialData GetSocialData(Guid userId)
        {
            return _repository.GetSocialData(userId);
        }
        #endregion

        #region Image Methods
        public bool CreateSocialImage(SocialImage socialImageToCreate)
        {
            // Validation logic
            if (!ValidateSocialImage(socialImageToCreate))
                return false;

            // Database logic
            try
            {
                _repository.CreateSocialImage(socialImageToCreate);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }
        
        public bool DeleteSocialImage(SocialImage socialImageToDelete)
        {
            try
            {
                _repository.DeleteSocialImage(socialImageToDelete);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }
        public bool EditSocialImage(SocialImage socialImageToEdit)
        {
            // Validation logic
            if (!ValidateSocialImage(socialImageToEdit))
                return false;

            // Database logic
            try
            {
                _repository.EditSocialImage(socialImageToEdit);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }

        public SocialImage GetSocialImage(string imageName, Guid userId)
        {
            return _repository.GetSocialImage(imageName, userId);
        }
        public SocialImage GetSocialImage(string imageName)
        {
            return _repository.GetSocialImage(imageName);
        }
        public SocialImage GetProfilePic(Guid userId)
        {
            return _repository.GetProfilePic(userId);
        }
        public IEnumerable<SocialImage> ListSocialImages(Guid userId)
        {
            return _repository.ListSocialImages(userId);
        }
        #endregion

        public bool CreateSocialLike(SocialLike socialLikeToCreate)
        {
            // Database logic
            try
            {
                
                var accountRepository = ServiceLocator.Current.GetInstance<IEntityAccountRepository>();


                socialLikeToCreate.Message = _repository.GetSocialMessage(socialLikeToCreate.Message.MessageID);
                socialLikeToCreate.Liker = accountRepository.GetUser(socialLikeToCreate.Liker.UserID);
                _repository.CreateSocialLike(socialLikeToCreate);
            }
            catch (Exception ex)
            {
                AppLogging.GetLogger().Error(GeneralMethods.GetStackNames(), ex);
                return false;
            }
            return true;
        }
    }
}